﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Media;
using System.Threading;
using Microsoft.DirectX.AudioVideoPlayback;
using System.IO;
using System.Xml;

namespace EasyPiano
{
    public partial class MainForm : Form
    {
        List<PictureBox> pbs = new List<PictureBox>();
        MusicRecord record = new MusicRecord();
        int oldS = 0;
        bool isRecording = false;
        HashSet<Keys> pressingKeys=new HashSet<Keys>();
        bool isSmallWindow = false;
        List<string> imagesPath = new List<string>();
        int currentPage = 1;
        int totalPage = 1;

        public MainForm()
        {
            InitializeComponent();
        }
       
        /// <summary>
        /// 重写系统Key处理事件
        /// </summary>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessDialogKey(Keys keyData)
        {

            if (keyData == Keys.Up || keyData == Keys.Down ||
                keyData == Keys.Left || keyData == Keys.Right ||
                keyData == Keys.Shift || keyData == Keys.Tab || keyData ==Keys.Alt)
            {
                return false;
            }
            else
            {
                return base.ProcessDialogKey(keyData);
            }
        }

        #region 自定义函数
        void UpdateImageCount()
        {
            if (pbs.Count == GlobalData.imageCount)
                return;

            //释放资源
            foreach (var item in pbs)
            {
                item.Dispose();
            }
            //清除
            pbs.Clear();
            this.tlp_images.ColumnStyles.Clear();
            this.tlp_images.Controls.Clear();

            this.tlp_images.ColumnCount = GlobalData.imageCount;
            for (int i = 0; i < GlobalData.imageCount; i++)
            {
                this.tlp_images.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 1f / GlobalData.imageCount * 100));
            }
            for (int i = 0; i < GlobalData.imageCount; i++)
            {
                PictureBox pb = new PictureBox();
                pb.Dock = System.Windows.Forms.DockStyle.Fill;
                pb.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
                this.tlp_images.Controls.Add(pb, i, 0);
                pbs.Add(pb);
            }

            CalcuPages();
            UpdatePage();
        }

        void CalcuPages()
        {
            totalPage = (int)Math.Ceiling(imagesPath.Count / (double)GlobalData.imageCount);
            if (totalPage > 0)
                currentPage = 1;
            else
                currentPage = 0;
        }

        void UpdatePage()
        {
            lb_page.Text = string.Format("第{0}页 , 共{1}页", currentPage, totalPage);

            if (currentPage > 0)
            {
                for (int i = 0; i < pbs.Count; i++)
                {
                    int j = (currentPage - 1) * GlobalData.imageCount + i;
                    if (j < imagesPath.Count)
                        pbs[i].ImageLocation = imagesPath[j];
                    else
                        pbs[i].ImageLocation = null;
                }
            }
        }

        void UpdateShowView()
        {
            int show = GlobalData.showView;

            if (show == 0)
            {
                kbc.Enabled = true;
                pkbc.Enabled = false;
                pan_keyboard.Height = 345;
                pan_piano.Height = 0;
                this.ActiveControl = null;
            }
            else if (show == 1)
            {
                kbc.Enabled = false;
                pkbc.Enabled = false;
                pan_keyboard.Height = 0;
                pan_piano.Height = 0;
                this.ActiveControl = null;
            }
            else if (show == 2)
            {
                kbc.Enabled = false;
                pkbc.Enabled = true;
                pan_keyboard.Height = 0;
                pan_piano.Height = 128;
                this.ActiveControl = null;
            }
            else if (show == 3)
            {
                kbc.Enabled = true;
                pkbc.Enabled = true;
                pan_keyboard.Height = 345;
                pan_piano.Height = 128;
                this.ActiveControl = null;
            }

            if (show == 0 || show == 3)
            {
                int keyboardView = GlobalData.keyboardView;
                if (keyboardView == 0)
                {
                    kbc.ShowTheme1();
                }
                else
                {
                    kbc.ShowTheme2();
                }
                this.ActiveControl = null;
            }

            if (show == 2 || show == 3)
            {
                pkbc.SetView(GlobalData.pianoKeyboardView);
            }
        }

        void DefaultLayout()
        {
            GlobalData.keyMusics.Clear();
            Keys[] keys = new Keys[] {
                Keys.F1,Keys.F2,Keys.F3,Keys.F4,Keys.F5,Keys.F6,Keys.F7,
                Keys.D1,Keys.D2,Keys.D3,Keys.D4,Keys.D5,Keys.D6,Keys.D7,
                Keys.Q,Keys.W,Keys.E,Keys.R,Keys.T, Keys.Y, Keys.U,
                Keys.A,Keys.S,Keys.D,Keys.F,Keys.G,Keys.H,Keys.J,
                Keys.Z,Keys.X,Keys.C,Keys.V,Keys.B,Keys.N,Keys.M
            };
            int[] soundId = new int[] {
                //4,6,8,9,11,13,15,
                16,18,20,21,23,25,27,
                28,30,32,33,35,37,39,
                40,42,44,45,47,49,51,
                52,54,56,57,59,61,63,
                64,66,68,69,71,73,75,
                //76,78,80,81,83,85,87
            };
            for (int i = 0; i < keys.Length; i++)
            {
                KeyMusic keyMusic = new KeyMusic(keys[i], soundId[i]);
                GlobalData.keyMusics.Add(keyMusic);
            }
            GlobalData.UpdateKeyMusicsMap();
            //Util.SaveLayout("35键布局.xml", GlobalData.keyMusics);
        }
        #endregion

        #region 事件

        private void Main_Load(object sender, EventArgs e)
        {
            System.Environment.CurrentDirectory = @"..\..\..";
            //读取文件
            GlobalData.Read();
            //加载声音
            DirectoryInfo folder = new DirectoryInfo(@"Sound");
            GlobalData.soundsPath = new string[folder.GetFiles().Length];
            for (int i = 0; i < GlobalData.soundsPath.Length; i++)
            {
                GlobalData.soundsPath[i] = folder.GetFiles()[i].Name;
            }
            //读取布局
            if (GlobalData.layoutPath == "" || GlobalData.layoutPath == null)
            {
                DefaultLayout();
            }
            else
            {
                try
                {
                    //避免玩家移动文件路径后，无法打开找到布局文件
                    GlobalData.keyMusics = Util.ReadLayout(GlobalData.layoutPath);
                    GlobalData.UpdateKeyMusicsMap();
                }
                catch
                {
                    DefaultLayout();
                    GlobalData.UpdateKeyMusicsMap();
                }                
            }

            UpdateImageCount();
            UpdateShowView();
            Util.CreateOutoutDevice();
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Util.DeleteOutputDevice();
            GlobalData.Save();
            System.Environment.Exit(0);
        }

        private void Main_KeyDown(object sender, KeyEventArgs e)
        {
            if (GlobalData.keyMusicsMap.ContainsKey(e.KeyCode))
            {
                #region 解决长按多次触发
                if (pressingKeys.Contains(e.KeyCode))
                {
                    return;
                }
                else
                {
                    pressingKeys.Add(e.KeyCode);
                }
                #endregion

                int soundIndex = GlobalData.keyMusicsMap[e.KeyCode] + GlobalData.offset;

                if (soundIndex >= 1 && soundIndex <= 88)
                {
                    if (GlobalData.continueSound == false)//简单模式
                    {
                        Util.AsynPlaySound(GlobalData.soundsPath[soundIndex]);

                        if (isRecording)//录音
                        {
                            int s = System.Environment.TickCount;
                            int delay = s - oldS;
                            oldS = s;
                            int n = record.TotalProgress;
                            if (n > 0)
                                record.SetSimpleDuration(n - 1, delay);

                            record.Add(soundIndex, 500);
                        }
                    }
                    else//持续发音模式
                    {
                        Util.StartPlay(soundIndex);

                        if (isRecording)//录音
                        {
                            int s = System.Environment.TickCount;
                            record.Add(soundIndex, true, s);
                        }
                    }
                }
            }
        }

        private void MainForm_KeyUp(object sender, KeyEventArgs e)
        {
            if (GlobalData.keyMusicsMap.ContainsKey(e.KeyCode))
            {
                #region 解决长按多次触发
                if (pressingKeys.Contains(e.KeyCode))
                {
                    pressingKeys.Remove(e.KeyCode);
                }
                #endregion

                if (GlobalData.continueSound)
                {
                    int soundIndex = GlobalData.keyMusicsMap[e.KeyCode] + GlobalData.offset;

                    if (soundIndex >= 1 && soundIndex <= 88)
                    {
                        Util.StopPlay(soundIndex);

                        if (isRecording)//录音
                        {
                            int s = System.Environment.TickCount;
                            record.Add(soundIndex, false, s);
                        }
                    }
                }
            }
        }

        private void pianoKeyboardControl1_Enter(object sender, EventArgs e)
        {
            this.ActiveControl = null;
        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            if (isSmallWindow)
            {
                TopMost = false;
                isSmallWindow = false;
            }
        }
        private void bt_left_page_Click(object sender, EventArgs e)
        {
            if (currentPage > 1)
            {
                currentPage--;
                UpdatePage();
            }
        }

        private void bt_right_page_Click(object sender, EventArgs e)
        {
            if (currentPage < totalPage)
            {
                currentPage++;
                UpdatePage();
            }
        }
        #endregion

        #region 菜单

        #region 文件
        private void mi_open_piano_Click(object sender, EventArgs e)
        {
            PianoKeyboardForm form = new PianoKeyboardForm();
            form.ShowDialog();
        }

        private void mi_open_record_Click(object sender, EventArgs e)
        {
            ofd_open_record.InitialDirectory = System.Environment.CurrentDirectory + "\\Record";
            if (ofd_open_record.ShowDialog() == DialogResult.OK)
            {
                string file = ofd_open_record.FileName;
                MusicRecordManagerForm form = new MusicRecordManagerForm();
                MusicRecord record = new MusicRecord();
                record.Read(file);
                form.record = record;
                form.Show();
            }
        }

        private void mi_open_keyboard_Click(object sender, EventArgs e)
        {
            KeyBoardForm form = new KeyBoardForm();
            form.ShowDialog();
        }

        private void mi_new_layout_Click(object sender, EventArgs e)
        {
            LayoutManagerForm form = new LayoutManagerForm();
            form.Show(this);
        }

        private void mi_exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void mi_open_layout_Click(object sender, EventArgs e)
        {
            ofd_open_layout.InitialDirectory = System.Environment.CurrentDirectory + "\\Layout";
            if (ofd_open_layout.ShowDialog() == DialogResult.OK)
            {
                string file = ofd_open_layout.FileName;
                LayoutManagerForm form = new LayoutManagerForm();
                form.layout = Util.ReadLayout(file);
                form.savePath = file;
                form.Show(this);
            }
        }

        private void mi_open_img_Click(object sender, EventArgs e)
        {
            ofd_open_img.InitialDirectory = System.Environment.CurrentDirectory + "\\MusicSoundPic";
            if (ofd_open_img.ShowDialog() == DialogResult.OK)
            {
                imagesPath.Clear();
                foreach (var path in ofd_open_img.FileNames)
                {
                    imagesPath.Add(path);
                }
                CalcuPages();
                UpdatePage();
            }
        }

        private void mi_new_music_score_Click(object sender, EventArgs e)
        {
            MusicScoreManagerForm form = new MusicScoreManagerForm();
            form.Show();
        }

        private void mi_open_music_score_Click(object sender, EventArgs e)
        {
            ofd_open_music_score.InitialDirectory = System.Environment.CurrentDirectory + "\\MusicScore";
            if (ofd_open_music_score.ShowDialog() == DialogResult.OK)
            {
                string file = ofd_open_music_score.FileName;
                MusicScoreManagerForm form = new MusicScoreManagerForm();
                Song song = new Song();
                song.Read(file);
                form.song = song;
                form.Show();
            }
        }
        #endregion

        #region 设置
        private void mi_set_playing_Click(object sender, EventArgs e)
        {
            SetPlayingForm form = new SetPlayingForm();
            if (form.ShowDialog() == DialogResult.OK)
            {
            }
        }

        private void mi_set_view_Click(object sender, EventArgs e)
        {
            SetViewForm form = new SetViewForm();
            if (form.ShowDialog() == DialogResult.OK)
            {
                UpdateShowView();
                UpdateImageCount();
            }
        }

        private void mi_reset_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确定要恢复默认设置吗，这样您之前的个性化设置将被重置，但是你创建的文件不会受影响。", "提醒", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
            {
                GlobalData.imageCount = 1;
                GlobalData.showView = 2;
                GlobalData.offset = 0;
                GlobalData.keyboardView = 0;
                GlobalData.volume = 100;
                GlobalData.layoutPath = "";
                GlobalData.continueSound = false;
                GlobalData.pianoKeyboardView = 0;

                DefaultLayout();
                UpdateShowView();
                UpdateImageCount();
            }
        }

        #endregion

        #region 工具
        private void mi_record_start_Click(object sender, EventArgs e)
        {
            isRecording = true;
            this.record.Clear();
            oldS = System.Environment.TickCount;
            record.startTime = oldS;
            if (GlobalData.continueSound)
                record.mode = 1;
        }

        private void mi_record_stop_Click(object sender, EventArgs e)
        {
            isRecording = false;
            InputMusicRecordDataForm form = new InputMusicRecordDataForm();
            form.record = record;
            form.ShowDialog();
        }

        private void mi_small_window_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.ClientSize = new Size(290, 0);
            TopMost = true;
            isSmallWindow = true;
        }

        #endregion

        #region 帮助
        private void mi_help_about_Click(object sender, EventArgs e)
        {
            AboutForm form = new AboutForm();
            form.ShowDialog();
        }

        private void mi_help_link_Click(object sender, EventArgs e)
        {
            ContactForm form = new ContactForm();
            form.ShowDialog();
        }

        #endregion

        #endregion


    }
}
